package com.jiaertangshi.jiaer.controller;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.startup.PasswdUserDatabase;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.jiaertangshi.jiaer.dto.Tbill;
import com.jiaertangshi.jiaer.dto.RequestParameter.ToderRequest;
import com.jiaertangshi.jiaer.service.BillService;
import com.jiaertangshi.jiaer.tools.PagingUtils;
import com.jiaertangshi.jiaer.tools.wechat.BeanUtil;
import com.jiaertangshi.jiaer.tools.wechat.DateUtil;
import com.jiaertangshi.jiaer.tools.wechat.JiaResult;
import com.jiaertangshi.jiaer.tools.wechat.RandomUtils;
import com.jiaertangshi.jiaer.tools.wechat.Signature;
import com.jiaertangshi.jiaer.tools.wechat.TbillUtils;
import com.jiaertangshi.jiaer.tools.wechat.WxParam;
import com.jiaertangshi.jiaer.tools.wechat.WxPayHttp;
import com.jiaertangshi.jiaer.tools.wechat.WxSPConfig;
import com.jiaertangshi.jiaer.tools.wechat.XmlUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;


@RequestMapping("/bill")
@RestController
public class BillController {

	public static final Logger logger = LoggerFactory.getLogger(BillController.class);
	
	@Autowired
	private BillService BillService;
	
	 /*微信通知异步回调*/
	@Value("${wechat.notify_url}")
    public  String  notify_url;

	/*
	 * 提交订单
	 * 所需参数：菜品id   每个菜品的数量
	 * 就餐人数    餐桌号   点餐类型   
	 * 备注信息   店铺id   点餐人openid
	 * 支付方式   用户密码 
	 * 金额
	 */
    @ApiOperation(value="用户下单和创建",notes="微信小程序创建订单以及统一下单程序的生成")
    @ApiImplicitParams({
    	@ApiImplicitParam(name="consumeAmount",value="消费总金额",required=true,dataType="Integer"),
    	@ApiImplicitParam(name="billPatn",value="消费模式(单点.堂食)",required=true,dataType="String"),
    	@ApiImplicitParam(name="payMethod",value="付款方式 1微信支付 2余额支付3奖金支付 ",required=true,dataType="String"),
    	@ApiImplicitParam(name="billingRatio",value="结算比例(商家折扣)",required=true,dataType="Integer"),
    	@ApiImplicitParam(name="payAmount",value="全款经过商家折扣后的金额",required=true,dataType="Integer"),
    	@ApiImplicitParam(name="commitDate",value="提交时间 ",required=true,dataType="Date"),
    	@ApiImplicitParam(name="billMark",value="订单备注",required=true,dataType="String"),
    	@ApiImplicitParam(name="userid",value="点餐人的Id",required=true,dataType="Integer"),
    	@ApiImplicitParam(name="shopid",value="商户Id ",required=true,dataType="Integer"),
    	@ApiImplicitParam(name="shopname",value="店铺名称",required=true,dataType="String"),
    	@ApiImplicitParam(name="toders",value="详细菜品数据",required=true,dataType="List"),   	
    })
	@RequestMapping(value = "/addBill/{openid}", method = RequestMethod.POST)
	public JiaResult  addBill(@PathVariable String openid,@RequestBody Tbill tbill,@RequestBody ToderRequest tods,HttpServletRequest request) throws Exception {
    	 logger.debug("支付的方式是"+tbill.getPayMethod()); 
    	//这里需要判断支付方式
    	 //微信支付的情况
    	 if(tbill.getPayMethod().equals("1")) {
    	    	if(tods.getToders().size()<=0 || StringUtils.isEmpty(openid)) {
    				return JiaResult.build(500, "请求微信支付失败");
    			}
    			//这里注入订单表的其他数据
    			tbill.setBillNo(TbillUtils.getOrderIdByTime());
    			//微信返回参数
    	        WxParam wxParam = new WxParam();
    	        try {
    				wxParam.setWxParam(wxParam,tbill,request,notify_url,openid,tods.getShopname());
    			} catch (UnsupportedEncodingException e) {
    				e.printStackTrace();
    			}
    	        //这里将实体类注入转换为Map集合
    	        Map<String, String> wxParamTOMap = BeanUtil.convertBeanToMap(wxParam);
    	        String sign = Signature.getSign(wxParamTOMap, WxSPConfig.MCH_KEY); //获取签名
    	        wxParamTOMap.put("sign",sign);//为这个map注入签名参数
    	        System.out.println("微信小程序支付请求的Map===>"+wxParamTOMap);
    	        try {
    	        	BillService.addOrader(tbill, tods.getToders());
    			} catch (Exception e) {
    				 logger.debug("创建订单时出现错误!");
    			     e.printStackTrace();
    			     return JiaResult.build(500,"创建订单失败,请重试!");
    			}
    	        //这里向微信统一支付开发接口发送请求
    	        String xmlResponse = WxPayHttp.doPostPayUnifiedOrder(WxSPConfig.UNIFIED_ORDER_URL, XmlUtil.createRequestXml(wxParamTOMap));
    	        //然后这里解析微信支付返回的文件
    	        Map<String,String> wxParamVO = parseXmlResponse(xmlResponse);
    	        logger.debug("返回的数据是"+JSONObject.fromObject(wxParamVO).toString());
    	        return	JiaResult.ok(wxParamVO);//然后将处理好的文件返回给微信小程序
    	 }
    	 //余额支付
    	 if(tbill.getPayMethod().equals("2")){
 	    	if(tbill.getUserid()==null) {
 				return JiaResult.build(500, "请求余额支付失败");
 			}
			//这里注入订单表的其他数据
			tbill.setBillNo(TbillUtils.getOrderIdByTime());
			return BillService.addTbillBalance(tbill, tods);
    	 }
    	 //奖金支付
    	 if(tbill.getPayMethod().equals("3")) {
  	    	if(tbill.getUserid()==null) {
  				return JiaResult.build(500, "请求奖金支付失败");
  			}
 			//这里注入订单表的其他数据
 			tbill.setBillNo(TbillUtils.getOrderIdByTime());
 			return	BillService.addTbillBonus(tbill, tods);
     	 }
    	 return JiaResult.build(500,"发起支付失败！");
      }
    
    @ApiOperation(value = "微信支付成功回调",notes = "微信支付成功异步回调,修改订单信息")
    @GetMapping("/notifyResult")
    public void notifyResultGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("微信回调requestGet===>"+request);
        notifyResult(request,response);
    }
 

    @ApiOperation(value = "微信支付成功回调",notes = "微信支付成功异步回调,修改订单信息")
    @PostMapping("/notifyResult")
    public void notifyResultPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("微信回调requestPOSt===>"+request);
        notifyResult(request,response);
    }
    
    
    private void notifyResult (HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("微信回调request===>"+request);
        //获取微信异步通知的数据
        Map<String, String> paramsToMap = XmlUtil.reqParamsToMap(request);
        logger.info("微信回调参数map===>"+paramsToMap);
        //校验微信的sign值
        boolean flag = Signature.validateSign(paramsToMap, WxSPConfig.MCH_KEY);
        if(flag){
        	//修改订单状态
        	Tbill tbill = BillService.geTbillByNo(paramsToMap.get("out_trade_no"));
        	logger.info("微信回调的流水号===>"+paramsToMap.get("out_trade_no"));
            //判断是否是未支付状态
            if(tbill.getBillState().equals("0")&&tbill.getDataStatus()){
                //更新订单状态
            	tbill.setBillState("1");
                tbill.setPayMethod("微信支付");
                tbill.setPayDate(new Date());//支付成功时间
                tbill.setUpdatedAt(new Date());//更新时间

                BillService.updateBill(tbill);
                //如果订单修改成功,通知微信接口不要在回调这个接口
                WxPayHttp.responseXmlSuccess(response);
            }
        }
    }
    
	/*解析微信请求响应的数据并返回小程序需要的数据*/
	private  Map<String,String> parseXmlResponse(String xmlResponse){
	    Map<String,String> resultMap=new HashMap<>();
	    //判断sign值是否正确
	    Boolean flag = Signature.validateResponseXmlToMap(xmlResponse);
	    if(flag){
	        Map<String, String> map = XmlUtil.xmlToMap(xmlResponse);
	        /*logger.info("微信支付请求响应的数据的预支付ID====>"+map.get("prepay_id"));*/
	        resultMap.put("appId",WxSPConfig.APP_ID_SMALL_PROGRAM);
	        resultMap.put("timeStamp",String.valueOf(DateUtil.strToTime(DateUtil.format(new Date()))));
	        resultMap.put("nonceStr",RandomUtils.generateString(32));
	        resultMap.put("package","prepay_id="+map.get("prepay_id"));
	        resultMap.put("signType","MD5");
	        String sign = Signature.getSign(resultMap, WxSPConfig.MCH_KEY);
	        resultMap.put("paySign",sign);
	    }
	    return resultMap;
	}
	
	@ApiOperation(value="根据用户Id获取到订单信息",notes="获取到订单信息")
	@ApiImplicitParam(name="userid",value="微信用户唯一的userid",required=true,dataType="Integer")
	@PostMapping(value="/getBillByUserId")
	public JiaResult getBillByUserId(@RequestBody Tbill tbill,@RequestBody PagingUtils paging) {
		if(tbill.getUserid()==null) {
			return JiaResult.build(500, "获取用户Id失败");
		}
		return BillService.getBillByUserId(tbill.getUserid(), paging.getPage(), paging.getSize());
	}
}
